package gitee

import (
	"bytes"
	"context"
	"crypto/subtle"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"gitee.com/openeuler/go-gitee/gitee"
	"github.com/antihax/optional"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/changedfiles"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/events"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/opscomments"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/params"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/params/triggertype"
	"github.com/openshift-pipelines/pipelines-as-code/pkg/provider"
	"go.uber.org/zap"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/yaml"
	"net/http"
	"strconv"
	"strings"
	"time"
)

const (
	taskStatusTemplate = `
<table>
  <tr><th>Status</th><th>Duration</th><th>Name</th></tr>

{{- range $taskrun := .TaskRunList }}
<tr>
<td>{{ formatCondition $taskrun.PipelineRunTaskRunStatus.Status.Conditions }}</td>
<td>{{ formatDuration $taskrun.PipelineRunTaskRunStatus.Status.StartTime $taskrun.Status.CompletionTime }}</td><td>

{{ $taskrun.ConsoleLogURL }}

</td></tr>
{{- end }}
</table>`
	noClientErrStr = `no gitee client has been initialized, exiting... (hint: did you forget setting a secret on your repo?)`
)

var _ provider.Interface = (*Provider)(nil)

type Provider struct {
	Client          *gitee.APIClient
	Logger          *zap.SugaredLogger
	run             *params.Run
	pacInfo         *info.PacOpts
	Token           *string
	targetProjectID int
	sourceProjectID int
	repoURL         string
	apiURL          string
	eventEmitter    *events.EventEmitter
	repo            *v1alpha1.Repository
	user            *gitee.UserHook
	owner           string
}

func (v *Provider) SetLogger(logger *zap.SugaredLogger) {
	v.Logger = logger
}

func (v *Provider) BuildRequest(ctx context.Context, run *params.Run, repo *v1alpha1.Repository, cluster, appEnv, branch, webhookSecret string) (*http.Request, error) {
	v.repo = repo
	v.run = run
	payload := &gitee.PushEvent{}
	cfg := gitee.NewConfiguration()

	gitInfo := strings.Split(strings.TrimPrefix(repo.Spec.URL, "https://gitee.com/"), "/")
	gitOwner := gitInfo[0]
	repoName := gitInfo[1]

	repoSecret, err := v.run.Clients.Kube.CoreV1().Secrets(repo.Namespace).Get(ctx, repo.Spec.GitProvider.Secret.Name, metav1.GetOptions{})
	if err != nil {
		v.Logger.Errorf("failed to get secret %s from namespace %s. err=>%v", repo.Spec.GitProvider.Secret.Name, repo.Namespace, err)
		return nil, err
	}

	repoToken := string(repoSecret.Data[repo.Spec.GitProvider.Secret.Key])

	cfg.AddDefaultHeader("access_token", repoToken)
	v.Client = gitee.NewAPIClient(cfg)
	v.apiURL = cfg.BasePath
	repoOpts := &gitee.GetV5ReposOwnerRepoOpts{
		AccessToken: optional.NewString(repoToken),
	}
	ownerRepo, _, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepo(ctx, gitOwner, repoName, repoOpts)
	if err != nil {
		v.Logger.Errorf("failed to get gitee reposOwnerRepo. err=>%v", err)
		return nil, err
	}

	userHook := &gitee.UserHook{
		Id:        ownerRepo.Owner.Id,
		Name:      ownerRepo.Owner.Name,
		Email:     ownerRepo.Owner.Email,
		Username:  ownerRepo.Owner.Name,
		UserName:  ownerRepo.Owner.Name,
		Url:       ownerRepo.Owner.HtmlUrl,
		Login:     ownerRepo.Owner.Login,
		AvatarUrl: ownerRepo.Owner.AvatarUrl,
		HtmlUrl:   ownerRepo.Owner.HtmlUrl,
		Type_:     ownerRepo.Owner.Type_,
		SiteAdmin: false,
		Time:      time.Time{},
		Remark:    "",
	}
	payload.Sender = userHook
	payload.User = userHook
	payload.Pusher = userHook

	htmlUrl := strings.TrimSuffix(ownerRepo.HtmlUrl, ".git")
	projectHook := &gitee.ProjectHook{
		Fork:              ownerRepo.Fork,
		CloneUrl:          ownerRepo.SshUrl,
		SvnUrl:            "",
		GitHttpUrl:        "",
		GitSshUrl:         "",
		GitSvnUrl:         "",
		Homepage:          ownerRepo.Homepage,
		StargazersCount:   ownerRepo.StargazersCount,
		WatchersCount:     ownerRepo.WatchersCount,
		ForksCount:        ownerRepo.ForksCount,
		Language:          ownerRepo.Language,
		HasIssues:         ownerRepo.HasIssues,
		HasWiki:           ownerRepo.HasWiki,
		HasPage:           ownerRepo.HasPage,
		License:           ownerRepo.License,
		OpenIssuesCount:   ownerRepo.OpenIssuesCount,
		NameWithNamespace: ownerRepo.FullName,
		PathWithNamespace: ownerRepo.FullName,
		Id:                ownerRepo.Id,
		Name:              ownerRepo.Name,
		FullName:          ownerRepo.FullName,
		Url:               htmlUrl,
		Path:              ownerRepo.Path,
		DefaultBranch:     ownerRepo.DefaultBranch,
		HtmlUrl:           htmlUrl,
		Private:           ownerRepo.Private,
		Description:       ownerRepo.Description,
		Owner:             userHook,
		GitUrl:            ownerRepo.Url,
		SshUrl:            ownerRepo.SshUrl,
		CreatedAt:         ownerRepo.CreatedAt,
		UpdatedAt:         ownerRepo.UpdatedAt,
		PushedAt:          ownerRepo.UpdatedAt,
		Namespace:         ownerRepo.Namespace.Name,
	}
	payload.Project = projectHook
	payload.Repository = projectHook
	commitOpts := &gitee.GetV5ReposOwnerRepoCommitsShaOpts{
		AccessToken: optional.NewString(repoToken),
	}
	commit, _, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoCommitsSha(ctx, gitOwner, repoName, branch, commitOpts)
	if err != nil {
		v.Logger.Errorf("failed to GetV5ReposOwnerRepoCommitsSha. err=>%v", err)
		return nil, err
	}
	commitHook := &gitee.CommitHook{
		Id:        commit.Sha,
		TreeId:    commit.Commit.Tree.Sha,
		ParentIds: nil,
		Message:   commit.Commit.Message,
		Timestamp: commit.Commit.Committer.Date,
		Url:       commit.HtmlUrl,
		Author:    userHook,
		Committer: userHook,
		Distinct:  false,
		Added:     nil,
		Removed:   nil,
		Modified:  nil,
	}
	payload.HeadCommit = commitHook
	payload.Commits = append(payload.Commits, *commitHook)

	ref := "refs/heads/" + branch
	payload.Ref = &ref

	body, err := json.Marshal(payload)
	if err != nil {
		v.Logger.Errorf("failed to Marshal payload. err=>%v", err)
		return nil, err
	}
	req, err := http.NewRequest("POST", "http://localhost:8080/manual", bytes.NewBuffer(body))
	if err != nil {
		v.Logger.Errorf("failed to create POST request. err=>%v", err)
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("X-GIT-OSCHINA-EVENT", "Push Hook")
	req.Header.Add("X-Gitee-Event", "Push Hook")
	req.Header.Add("User-Agent", "git-oschina-hook")
	req.Header.Add("X-Gitee-Ping", "false")
	req.Header.Add("X-Gitee-Token", webhookSecret)
	return req, nil
}

func (v *Provider) Validate(ctx context.Context, params *params.Run, event *info.Event) error {
	token := event.Request.Header.Get("X-Gitee-Token")
	if event.Provider.WebhookSecret == "" && token != "" {
		return fmt.Errorf("gitee failed validation: failed to find webhook secret")
	}

	if subtle.ConstantTimeCompare([]byte(event.Provider.WebhookSecret), []byte(token)) == 0 {
		return fmt.Errorf("gitee failed validation: event's secret doesn't match with webhook secret")
	}
	return nil
}

func (v *Provider) Detect(req *http.Request, payload string, logger *zap.SugaredLogger) (bool, bool, *zap.SugaredLogger, string, error) {
	isGL := false
	eventType := req.Header.Get("X-Gitee-Event")
	if eventType == "" {
		return false, false, logger, "no gitee event", nil
	}

	// it is a Gitee event
	isGL = true

	setLoggerAndProceed := func(processEvent bool, reason string, err error) (bool, bool, *zap.SugaredLogger,
		string, error,
	) {
		logger = logger.With("provider", "gitee", "event-id", req.Header.Get("X-Request-Id"))
		return isGL, processEvent, logger, reason, err
	}
	convertedEventType := convertEventType(eventType)
	eType, err := gitee.ParseWebHook(convertedEventType, []byte(payload))
	if err != nil {
		return setLoggerAndProceed(false, "", err)
	}
	if eType != "" {
		return setLoggerAndProceed(true, "", nil)
	}

	return setLoggerAndProceed(false, "no gitee event", nil)
}

func (v *Provider) ParsePayload(ctx context.Context, run *params.Run, request *http.Request, payload string) (*info.Event, error) {
	// TODO: parse request to figure out which event
	var processedEvent *info.Event

	eventType := request.Header.Get("X-Gitee-Event")
	if eventType == "" {
		return nil, fmt.Errorf("failed to find event type in request header")
	}

	payloadB := []byte(payload)
	convertedEventType := convertEventType(eventType)
	eventInt, err := gitee.ParseWebHook(convertedEventType, payloadB)
	if err != nil {
		return nil, err
	}
	_ = json.Unmarshal(payloadB, &eventInt)

	switch gitEvent := eventInt.(type) {
	case *gitee.PullRequestEvent:
		processedEvent = info.NewEvent()
		processedEvent.Provider.User = gitEvent.Sender.UserName
		processedEvent.Sender = gitEvent.Sender.UserName
		processedEvent.DefaultBranch = gitEvent.Repository.DefaultBranch
		processedEvent.URL = gitEvent.Repository.Url
		processedEvent.SHA = gitEvent.PullRequest.Head.Sha
		processedEvent.SHAURL = fmt.Sprintf("%s/commit/%s", gitEvent.PullRequest.HtmlUrl, processedEvent.SHA)
		processedEvent.HeadBranch = gitEvent.PullRequest.Head.Ref
		processedEvent.BaseBranch = gitEvent.PullRequest.Base.Ref
		processedEvent.HeadURL = gitEvent.PullRequest.Head.Repo.HtmlUrl
		processedEvent.BaseURL = gitEvent.PullRequest.Base.Repo.HtmlUrl
		processedEvent.PullRequestNumber = int(gitEvent.Number)
		processedEvent.PullRequestTitle = gitEvent.PullRequest.Title
		processedEvent.Organization = gitEvent.Repository.Namespace
		processedEvent.Repository = gitEvent.Repository.Path
		processedEvent.TriggerTarget = triggertype.PullRequest
		processedEvent.EventType = triggertype.PullRequest.String()
		v.user = gitEvent.GetSender()
	case *gitee.PushEvent:
		processedEvent = info.NewEvent()
		processedEvent.SHA = gitEvent.HeadCommit.Id
		if processedEvent.SHA == "" {
			processedEvent.SHA = *gitEvent.Before
		}
		processedEvent.SHAURL = gitEvent.HeadCommit.Url
		processedEvent.SHATitle = gitEvent.HeadCommit.Message
		processedEvent.Organization = gitEvent.Repository.Namespace
		processedEvent.Repository = gitEvent.Repository.Path
		processedEvent.DefaultBranch = gitEvent.Repository.DefaultBranch
		processedEvent.URL = gitEvent.Repository.HtmlUrl
		processedEvent.Provider.User = gitEvent.Sender.UserName
		processedEvent.Sender = gitEvent.Sender.UserName
		processedEvent.BaseBranch = *gitEvent.Ref
		processedEvent.EventType = eventType
		processedEvent.HeadBranch = processedEvent.BaseBranch // in push events Head Branch is the same as BaseBranch
		processedEvent.BaseURL = gitEvent.Repository.HtmlUrl
		processedEvent.HeadURL = processedEvent.BaseURL // in push events Head URL is the same as BaseURL
		processedEvent.TriggerTarget = triggertype.Push
		if request.Host == "localhost:8080" {
			processedEvent.ManualTrigger = true
			processedEvent.ManualTriggerCluster = request.Header.Get("repo-cluster")
			processedEvent.ManualTriggerAppEnv = request.Header.Get("repo-appEnv")
		}
		v.user = gitEvent.GetUser()
	case *gitee.IssueEvent:
		if gitEvent.Issue == nil {
			return info.NewEvent(), fmt.Errorf("issue comment is not coming from a pull_request")
		}
		processedEvent = info.NewEvent()
		processedEvent.Organization = gitEvent.Repository.Namespace
		processedEvent.Repository = gitEvent.Repository.Path
		processedEvent.Provider.User = gitEvent.Sender.UserName
		processedEvent.Sender = gitEvent.Sender.UserName
		processedEvent.TriggerTarget = triggertype.Comment
		opscomments.SetEventTypeAndTargetPR(processedEvent, gitEvent.Issue.Title)
		number, err := strconv.Atoi(gitEvent.Issue.Number)
		if err != nil {
			return nil, fmt.Errorf("failed to convert gitEvent.Issue.Number to number. err=>%v", eventType)
		}
		processedEvent.PullRequestNumber = number
		if err != nil {
			return nil, err
		}
		processedEvent.URL = gitEvent.Repository.HtmlUrl
		processedEvent.DefaultBranch = gitEvent.Repository.DefaultBranch
		v.user = gitEvent.GetUser()
	default:
		return nil, fmt.Errorf("event %s is not supported", eventType)
	}

	processedEvent.Event = eventInt
	return processedEvent, nil
}

func (v *Provider) CreateStatus(ctx context.Context, event *info.Event, statusOpts provider.StatusOpts) error {
	return nil
}

func (v *Provider) GetTektonDir(ctx context.Context, runevent *info.Event, path, provenance string) (string, error) {
	if v.Client == nil {
		return "", fmt.Errorf("no gitlab client has been initialized, " +
			"exiting... (hint: did you forget setting a secret on your repo?)")
	}
	// default set provenance from head
	revision := runevent.DefaultBranch // 从主分支获取pipeline文件
	if provenance == "default_branch" {
		revision = runevent.DefaultBranch
		v.Logger.Infof("Using PipelineRun definition from default_branch: %s", runevent.DefaultBranch)
	} else {
		v.Logger.Infof("Using PipelineRun definition from source merge request SHA: %s", runevent.SHA)
	}

	opts := &gitee.GetV5ReposOwnerRepoContentsPathOpts{
		Ref:         optional.NewString(revision),
		AccessToken: optional.NewString(runevent.Provider.Token),
	}
	dirPath, resp, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoContentsDirPath(ctx, runevent.Organization, runevent.Repository, path, opts)
	if err != nil {
		return "", err
	}

	if resp != nil && resp.StatusCode == http.StatusNotFound {
		return "", nil
	}
	if err != nil {
		return "", fmt.Errorf("failed to list %s dir: %w", path, err)
	}

	return v.concatAllYamlFiles(ctx, dirPath, runevent)
}

// concatAllYamlFiles concat all yaml files from a directory as one big multi document yaml string.
func (v *Provider) concatAllYamlFiles(ctx context.Context, objects []gitee.Content, runevent *info.Event) (string, error) {
	var allTemplates string
	for _, value := range objects {
		if strings.HasSuffix(value.Name, ".yaml") ||
			strings.HasSuffix(value.Name, ".yml") {
			opts := &gitee.GetV5ReposOwnerRepoContentsPathOpts{
				Ref:         optional.NewString(runevent.DefaultBranch),
				AccessToken: optional.NewString(runevent.Provider.Token),
			}
			data, _, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(ctx, runevent.Organization, runevent.Repository, value.Path, opts) // 从主分支获取pipeline文件
			if err != nil {
				return "", err
			}
			decodeBytes, err := base64.StdEncoding.DecodeString(data.Content)
			if err != nil {
				return "", fmt.Errorf("error decode String  file %s: %w", value.Path, err)
			}
			// validate yaml
			var i any
			if err = yaml.Unmarshal(decodeBytes, &i); err != nil {
				return "", fmt.Errorf("error unmarshalling yaml file %s: %w", value.Path, err)
			}
			if allTemplates != "" && !strings.HasPrefix(string(decodeBytes), "---") {
				allTemplates += "---"
			}
			allTemplates += "\n" + string(decodeBytes) + "\n"
		}
	}

	return allTemplates, nil
}

func (v *Provider) GetFileInsideRepo(ctx context.Context, runevent *info.Event, path, target string) (string, error) {
	ref := runevent.SHA
	if target != "" {
		ref = runevent.BaseBranch
	}

	opts := &gitee.GetV5ReposOwnerRepoContentsPathOpts{Ref: optional.NewString(ref), AccessToken: optional.NewString(runevent.Provider.Token)}
	content, _, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(ctx, runevent.Organization, runevent.Repository, path, opts)
	if err != nil {
		return "", err
	}

	// base64 decode to string
	decoded, err := base64.StdEncoding.DecodeString(content.Content)
	if err != nil {
		return "", err
	}
	return string(decoded), nil
}

func (v *Provider) SetClient(ctx context.Context, run *params.Run, runevent *info.Event, repository *v1alpha1.Repository, emitter *events.EventEmitter) error {
	var err error

	if runevent.Provider.Token == "" {
		return fmt.Errorf("no git_provider.secret has been set in the repo crd")
	}
	cfg := gitee.NewConfiguration()
	cfg.AddDefaultHeader("access_token", runevent.Provider.Token)
	v.Client = gitee.NewAPIClient(cfg)

	v.apiURL = cfg.BasePath
	v.repoURL = runevent.Provider.URL
	v.eventEmitter = emitter
	v.repo = repository
	v.run = run
	v.owner = runevent.Organization
	err = provider.SetupPipelineFiles(v, v.Logger, runevent, run, repository)
	if err != nil {
		return fmt.Errorf("failed to set pipeline files. err=>%v", err)
	}
	return nil
}

func (v *Provider) SetPacInfo(pacInfo *info.PacOpts) {
	v.pacInfo = pacInfo
}

func (v *Provider) GetCommitInfo(ctx context.Context, runevent *info.Event) error {
	if v.Client == nil {
		return fmt.Errorf(noClientErrStr)
	}
	// 更新token的用户信息
	userOpts := &gitee.GetV5UserOpts{
		AccessToken: optional.NewString(runevent.Provider.Token),
	}
	tokenUser, _, err := v.Client.UsersApi.GetV5User(ctx, userOpts)
	if err != nil {
		return fmt.Errorf("failed to get user from gitee token. err=>%v", err)
	}
	runevent.TokenUser = tokenUser.Login
	// if we don't have an SHA (ie: incoming-webhook) then get it from the branch
	// and populate in the runevent.
	if runevent.SHA == "" && runevent.HeadBranch != "" {
		opts := &gitee.GetV5ReposOwnerRepoBranchesBranchOpts{AccessToken: optional.NewString(runevent.Provider.Token)}
		branchInfo, _, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoBranchesBranch(ctx, runevent.Organization, runevent.Repository, runevent.HeadBranch, opts)
		if err != nil {
			return err
		}
		runevent.SHA = branchInfo.Commit.Sha
		runevent.SHATitle = branchInfo.Commit.Sha
		runevent.SHAURL = branchInfo.Commit.Url
	}
	return nil
}

func (v *Provider) GetConfig() *info.ProviderConfig {
	return &info.ProviderConfig{
		TaskStatusTMPL: taskStatusTemplate,
		APIURL:         v.apiURL,
		Name:           "gitee",
		SkipEmoji:      true,
	}
}

func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedfiles.ChangedFiles, error) {
	if v.Client == nil {
		return changedfiles.ChangedFiles{}, fmt.Errorf("no gitee client has been initialized, " +
			"exiting... (hint: did you forget setting a secret on your repo?)")
	}
	if runevent.TriggerTarget == triggertype.PullRequest {

		opts := &gitee.GetV5ReposOwnerRepoPullsNumberFilesOpts{AccessToken: optional.NewString(runevent.Provider.Token)}
		mrChanges, _, err := v.Client.PullRequestsApi.GetV5ReposOwnerRepoPullsNumberFiles(ctx, runevent.Organization, runevent.Repository, int32(runevent.PullRequestNumber), opts)
		if err != nil {
			return changedfiles.ChangedFiles{}, err
		}
		changedFiles := changedfiles.ChangedFiles{}
		for _, change := range mrChanges {
			changedFiles.All = append(changedFiles.All, change.Patch.NewPath)
			if change.Patch.NewFile {
				changedFiles.Added = append(changedFiles.Added, change.Patch.NewPath)
			}
			if change.Patch.DeletedFile {
				changedFiles.Deleted = append(changedFiles.Deleted, change.Patch.NewPath)
			}
			if !change.Patch.RenamedFile && !change.Patch.DeletedFile && !change.Patch.NewFile {
				changedFiles.Modified = append(changedFiles.Modified, change.Patch.NewPath)
			}
			if change.Patch.RenamedFile {
				changedFiles.Renamed = append(changedFiles.Renamed, change.Patch.NewPath)
			}
		}
		return changedFiles, nil
	}

	if runevent.TriggerTarget == triggertype.Push {
		changedFiles := changedfiles.ChangedFiles{}
		return changedFiles, nil
	}
	return changedfiles.ChangedFiles{}, nil
}

func (v *Provider) GetTaskURI(ctx context.Context, event *info.Event, uri string) (bool, string, error) {
	return false, "", nil
}

func (v *Provider) CreateToken(ctx context.Context, i []string, event *info.Event) (string, error) {
	return "", nil
}

func (v *Provider) CheckFileExist(ctx context.Context, runevent *info.Event, branch, filename string) (bool, error) {
	if v.Client == nil {
		return false, fmt.Errorf("no gitee client has been initialized, " +
			"exiting... (hint: did you forget setting a secret on your repo?)")
	}
	fileBranch := runevent.DefaultBranch
	if branch != "" {
		fileBranch = branch

	}
	opts := &gitee.GetV5ReposOwnerRepoContentsPathOpts{
		Ref:         optional.NewString(fileBranch),
		AccessToken: optional.NewString(runevent.Provider.Token),
	}
	file, r, err := v.Client.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(ctx, runevent.Organization, runevent.Repository, filename, opts)
	if err != nil || r.StatusCode != http.StatusOK {
		return false, fmt.Errorf("error on get %s in gitee repository. err=>%v", filename, err)
	} else if r.StatusCode == http.StatusOK && file.Name == "" {
		return false, nil
	}
	return true, nil
}

func (v *Provider) CreateFile(ctx context.Context, runevent *info.Event, branch, filename, content string) error {
	if v.Client == nil {
		return fmt.Errorf("no gitee client has been initialized, " +
			"exiting... (hint: did you forget setting a secret on your repo?)")
	}
	fileBranch := runevent.DefaultBranch
	if branch != "" {
		fileBranch = branch

	}
	newfileParam := gitee.NewFileParam{
		Branch:      fileBranch,
		Content:     base64.StdEncoding.EncodeToString([]byte(content)),
		Message:     provider.PipelineCommitMsg,
		AccessToken: runevent.Provider.Token,
	}
	path, h, err := v.Client.RepositoriesApi.PostV5ReposOwnerRepoContentsPath(ctx, runevent.Organization, runevent.Repository, filename, newfileParam)
	if h.StatusCode == http.StatusCreated && path.Content.Path == filename {
		return nil
	} else if err != nil {
		v.Logger.Errorf("error on create %s in gitee repository. err=>%v", filename, err)
		return err
	} else if h.StatusCode == http.StatusBadRequest {
		v.Logger.Warnf("A file with this name already exists")
		return nil
	}
	return nil
}

func convertEventType(eventType string) string {
	switch eventType {
	case "push_hooks":
		return "Push Hook"
	case "issue_hooks":
		return "Issue Hook"
	case "merge_request_hooks":
		return "Merge Request Hook"
	case "note_hooks":
		return "Note Hook"
	default:
		return "Push Hook"
	}
}
